#ifndef _imageFuncs2_h_
#define _imageFuncs2_h_

// imageFuncs2.h
//
// non-member image functions that take 2 image arguments

#include "image/imageTmpl.h"
#include "image/imageTools.h"

namespace simple{
    //
    // 2 argument add
    //

    template<class R, class T1, class T2, class T3,
             class S1, class S2, class S3>
    void _add2 (const R&, const Image<T1,S1>& src1, const Image<T2,S2>& src2, Image<T3,S3>& dst1)
    {
        // Operate on each pixel 
        typename Image<T1,S1>::row_iterator i1 = src1.row_begin();
        typename Image<T2,S2>::row_iterator i2 = src2.row_begin();
        typename Image<T3,S3>::row_iterator i3 = dst1.row_begin();
        unsigned int w = src1.width ();
        const T1* p1;
        const T2* p2;
        T3* p3;
        for (; i1 != src1.row_end(); i1++, i2++, i3++) {
            p1 = i1->p;
            p2 = i2->p;
            p3 = i3->p;
            for (unsigned int x=0; x<w; x++)
                *p3++ = add2<T3> (*p1++, *p2++); // *p3++ = *p1++ + *p2++;
             // add2 (*p1++, *p2++, *p3++);      // *p3++ = *p1++ + *p2++;
        }
    }


template<class T1, class T2, class T3, 
         class S1, class S2, class S3>
void add (const Image<T1,S1>& src1, 
          const Image<T2,S2>& src2,
          Image<T3,S3>& dst1)
{
    Function_s1s2d1<T3,T1,T2,T3,S1,S2,S3> processor (_add2);
    processor.run (src1, src2, dst1);
}



template<class T1, class T2, class S1, class S2>
Image<T1,S1> operator+ (const Image<T1,S1>& src1, 
                             const Image<T2,S2>& src2)
{
    // Get our types from the first parameter
    Image<T1,S1> dst;
    add (src1, src2, dst);
    return dst;
}

    //
    // 2 argument sub
    //
    template<class R, class T1, class T2, class T3,
             class S1, class S2, class S3>
    void _sub2 (const R&, const Image<T1,S1>& src1, const Image<T2,S2>& src2, Image<T3,S3>& dst1)
    {
        // Operate on each pixel 
        typename Image<T1,S1>::row_iterator i1 = src1.row_begin();
        typename Image<T2,S2>::row_iterator i2 = src2.row_begin();
        typename Image<T3,S3>::row_iterator i3 = dst1.row_begin();
        unsigned int w = src1.width ();
        const T1* p1;
        const T2* p2;
        T3* p3;
        for (; i1 != src1.row_end(); i1++, i2++, i3++) {
            p1 = i1->p;
            p2 = i2->p;
            p3 = i3->p;
            for (unsigned int x=0; x<w; x++)
                *p3++ = sub2<T3> (*p1++, *p2++);  // *p3++ = *p1++ - *p2++;
             // sub2 (*p1++, *p2++, *p3++);       // *p3++ = *p1++ - *p2++;
        }
    }


    template<class T1, class T2, class T3, 
             class S1, class S2, class S3>
    void sub (const Image<T1,S1>& src1, 
              const Image<T2,S2>& src2,
              Image<T3,S3>& dst1)
    {
        Function_s1s2d1<T3,T1,T2,T3,S1,S2,S3> processor (_sub2);
        processor.run (src1, src2, dst1);
    }



    template<class T1, class T2, class S1, class S2>
    Image<T1,S1> operator- (const Image<T1,S1>& src1, 
                                 const Image<T2,S2>& src2)
    {
        // Get are types from the first parameter
        Image<T1,S1> dst;
        sub (src1, src2, dst);
        return dst;
    }

}
#endif // _imageFuncs2_h_
